from PyQt4 import QtGui, QtCore
from gSystem import signal, findFiles, LOG_DIR, IMAGE_EXTENSIONS, ORDER_LAYER
from gSystem import mainWindow as sysWindow
from gJson import loadObject, loadString, jsondump, jsonload
import os, os.path, time

class chatLineEdit(QtGui.QLineEdit):

    def __init__(self, mainWindow):
        super(QtGui.QLineEdit, self).__init__(mainWindow)
        self.position = 0
        self.messageHistory = []
        self.lastInput = ''

    def addMessage(self, mes):
        self.messageHistory.append(mes)
        self.position = len(self.messageHistory)

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Up and self.position > 0:
            #print "up!"
            if self.position == len(self.messageHistory):
                self.lastInput = self.text()
            self.position -= 1
            self.setText(self.messageHistory[self.position])
        elif event.key() == QtCore.Qt.Key_Down:
            #print "down!"
            if self.position < len(self.messageHistory) - 1:
                self.position += 1
                self.setText(self.messageHistory[self.position])
            elif self.position == len(self.messageHistory) - 1:
                self.setText(self.lastInput)
                self.position += 1
        QtGui.QLineEdit.keyPressEvent(self, event)

class chatWidget(QtGui.QDockWidget):

    def __init__(self, mainWindow):
        super(QtGui.QDockWidget, self).__init__(mainWindow)
        self.setToolTip(self.tr("A widget for chat and system messages."))
        self.setWindowTitle(self.tr("Chat"))
        self.setFeatures(QtGui.QDockWidget.DockWidgetFeatures(0))
        self.widgetEditor = QtGui.QTextBrowser(mainWindow)
        self.widgetLineInput = chatLineEdit(mainWindow)
        self.widgetLineInput.setToolTip(self.tr("Type text here and press Enter or Return to transmit it."))
        self.widget = QtGui.QWidget(mainWindow)
        self.widgetEditor.setReadOnly(True)
        self.widgetEditor.setOpenLinks(False)
        self.playerList = QtGui.QListWidget(mainWindow)
        self.layout = QtGui.QBoxLayout(2)
        self.layout.addWidget(self.widgetEditor)
        self.layout.addWidget(self.widgetLineInput)
        self.greaterLayout = QtGui.QBoxLayout(1)
        self.greaterLayout.addWidget(self.playerList)
        self.greaterLayout.addLayout(self.layout)
        self.widget.setLayout(self.greaterLayout)
        self.setWidget(self.widget)
        mainWindow.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self)
        
        self.widgetLineInput.returnPressed.connect(self.processInput)
    
    def insertMessage(self, mes):
        self.scroll = (self.widgetEditor.verticalScrollBar().value() ==
                   self.widgetEditor.verticalScrollBar().maximum())
        self.widgetEditor.append(mes)
        if self.scroll:
            self.widgetEditor.verticalScrollBar().setValue(self.widgetEditor.verticalScrollBar().maximum())
        try:
            try:
                self.logfile = open(os.path.join(LOG_DIR, time.strftime("%b_%d_%Y.log", time.localtime())), 'a')
                self.logfile.write(mes+"\n")
            finally:
                self.logfile.close()
        except:
            pass
    
    def processInput(self):
        self.newmes = unicode(self.widgetLineInput.text())
        self.widgetLineInput.clear()
        self.widgetLineInput.addMessage(self.newmes)
        self.chatInput.emit(self.newmes)
        
    def addPlayer(self, name):
        self.playerList.addItem(QtGui.QListWidgetItem(name))
    
    chatInput = signal(basestring, doc=
        """Called when chat input is received.
        
        text -- the message entered
        
        """
    )
    
class troopDisplay(QtGui.QWidget):
    
    def __init__(self, mainWindow, troop, num):
        super(QtGui.QWidget, self).__init__(mainWindow)
        self.layout = QtGui.QBoxLayout(2)
        self.layout.addWidget(QtGui.QLabel("".join(["Troop ",
                                                    str(num+1),
                                                    "\n  Strength:  ",
                                                    str(troop.number),
                                                    "\n  Race:  ",
                                                    str(troop.race),
                                                    "\n  Profession:  ",
                                                    str(troop.profession),
                                                    "\n  Primary Weapon:  ",
                                                    str(troop.weapon)])))
        self.setLayout(self.layout)
    
class unitInfoWidget(QtGui.QDockWidget):
    
    def __init__(self, mainWindow):
        super(QtGui.QDockWidget, self).__init__(mainWindow)
        self.setToolTip(self.tr("Displays info about currently selected army."))
        self.setWindowTitle(self.tr("Army"))
        self.setFeatures(QtGui.QDockWidget.DockWidgetFeatures(0)) #Unmoveable/closable/etc
        self.widget = QtGui.QWidget(mainWindow)
        self.layout = QtGui.QBoxLayout(2)
        self.commanderDisplay = QtGui.QLabel("")
        self.ownerDisplay = QtGui.QLabel("")
        self.troopDisplays = []
        self.layout.addWidget(self.commanderDisplay)
        self.layout.addWidget(self.ownerDisplay)
        self.widget.setLayout(self.layout)
        self.setWidget(self.widget)
        self._movetiles = []
        
        mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, self)
        
        self.hide()
        
    def uberHide(self):
        self.destroyMoveTiles()
        self.hide()
        
    def updateInfo(self, unit, mainWindow, requestingFaction):
        if unit.commander is not None:
            self.commanderDisplay.setText(unit.commander.name)
        else:
            self.commanderDisplay.setText("(No Commander)")
        self.ownerDisplay.setText(unit._owner)
        for item in self.troopDisplays:
            self.layout.removeWidget(item)
        self.troopDisplays = []
        for i, troop in enumerate(unit.troops):
            self.troopDisplays.append(troopDisplay(mainWindow, troop, i))
        for widg in self.troopDisplays:
            self.layout.addWidget(widg)
        if requestingFaction == unit._owner:
            self.createMoveTiles(unit)
            
    def createMoveTiles(self, unit):
        self.destroyMoveTiles()
        for coord in unit._movequeue:
            self._movetiles.append(sysWindow.glwidget.createImage(os.path.join("data", "images", "movetile.png"), ORDER_LAYER, 
                                                        (0, 0, 31, 31), 
                                                        (coord[0]*32, coord[1]*32, 32, 32)))
                                                
    def destroyMoveTiles(self):
        for tile in self._movetiles:
            tile.destroy()
        self._movetiles = []
            
class gameControlWidget(QtGui.QToolBar):

    def __init__(self, mainWindow):
        super(QtGui.QToolBar, self).__init__(mainWindow)
        self.setToolTip(self.tr("Myon"))
        self.currentTurn = 1
        self.turnLabel = QtGui.QLabel("Turn " + str(self.currentTurn))
        self.turnLabel.setFrameStyle(1)
        self.turnButton = QtGui.QPushButton("End Turn", mainWindow)
        self.domButton = QtGui.QPushButton("Domestic", mainWindow)
        self.perButton = QtGui.QPushButton("Personnel", mainWindow)
        self.ecoButton = QtGui.QPushButton("Economic", mainWindow)
        self.dipButton = QtGui.QPushButton("Diplomacy", mainWindow)
        self.espButton = QtGui.QPushButton("Espionage", mainWindow)
        self.addWidget(self.domButton)
        self.addWidget(self.perButton)
        self.addWidget(self.ecoButton)
        self.addWidget(self.dipButton)
        self.addWidget(self.espButton)
        self.addSeparator()
        self.addWidget(self.turnLabel)
        self.addSeparator()
        self.addWidget(self.turnButton)
        self.setFloatable(False)
        self.setMovable(False)
        mainWindow.addToolBar(self)
        
        self.turnButton.clicked.connect(self.callForTurn)
        self.domButton.clicked.connect(self.callForDom)
        self.perButton.clicked.connect(self.callForPers)
        self.ecoButton.clicked.connect(self.callForEco)
        self.dipButton.clicked.connect(self.callForDiplo)
        self.espButton.clicked.connect(self.callForEsp)
        
    def callForTurn(self):
        self.endTurn.emit()
        
    def callForDom(self):
        self.domSig.emit()
        
    def callForPers(self):
        self.persSig.emit()
        
    def callForEco(self):
        self.ecoSig.emit()
        
    def callForDiplo(self):
        self.diploSig.emit()
        
    def callForEsp(self):
        self.espSig.emit()
        
    def advanceTurn(self):
        self.currentTurn += 1
        self.turnLabel.setText("Turn " + str(self.currentTurn))
    
    endTurn = signal(doc=
        """Called when a player indicates willigness to advance the turn.
        
        """
    )
    
    domSig = signal(doc=
        """Called when a player wants to open the domestic menu.
        
        """
    )
    
    persSig = signal(doc=
        """Called when a player wants to open the personnel menu.
        
        """
    )
    
    ecoSig = signal(doc=
        """Called when a player wants to open the economic menu.
        
        """
    )
    
    diploSig = signal(doc=
        """Called when a player wants to open the diplomacy menu.
        
        """
    )
    
    espSig = signal(doc=
        """Called when a player wants to open the espionage menu.
        
        """
    )
    
class userListWidget(QtGui.QDockWidget):
    """The list of connected users."""
    
    def __init__(self, mainWindow):
        """Initializes the user list."""
        super(QtGui.QDockWidget, self).__init__(mainWindow)
        self.setToolTip(self.tr("People presently playing."))
        self.setWindowTitle(self.tr("Connected Users"))
        self.widget = QtGui.QWidget(mainWindow)
        self.listOfUsers = QtGui.QListWidget(mainWindow)
        self.listOfUsers.setSelectionMode(0)
        self.internalList = []
        self.complete = []
        self.layout = QtGui.QGridLayout()
        self.layout.addWidget(self.listOfUsers, 0, 0)
        self.widget.setLayout(self.layout)
        self.widget.setMaximumWidth(200) #Arbitrary; keeps it from taking over 1/3 of the screen
        self.setWidget(self.widget)
        mainWindow.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self)
        
    def addUser(self, name, host=False):
        self.internalList.append((name, host))
        nametmp = name
        if host:
            nametmp = "[Host] " + nametmp
        self.listOfUsers.addItem(nametmp)
        self.complete.append(False)
        
    def getUserByName(self, name):
        for i, item in enumerate(self.internalList):
            if item[0] == name:
                return i
        
    def removeUser(self, name):
        usrnum = self.getUserByName(name)
        self.internalList.pop(usrnum)
        self.complete.pop(usrnum)
        self.listOfUsers.takeItem(usrnum)
        
    def changeUserAppend(self, name, appe):
        usrnum = self.getUserByName(name)
        if self.internalList[usrnum][1]:
            self.listOfUsers.item(usrnum).setText("[Host] " + self.internalList[usrnum][0] + appe)
        else:
            self.listOfUsers.item(usrnum).setText(self.internalList[usrnum][0] + appe)
            
    def finishTurn(self, name):
        usrnum = self.getUserByName(name)
        self.complete[usrnum] = True
        self.listOfUsers.item(usrnum).setBackgroundColor(QtGui.QColor(90, 90, 90))
        
    def advanceTurn(self):
        for i in range(0, len(self.complete)):
            self.complete[i] = False
        self.listOfUsers.clear()
        for usrdat in self.internalList:
            nametmp = usrdat[0]
            if usrdat[1]:
                nametmp = "[Host] " + nametmp
            self.listOfUsers.addItem(nametmp)
            
    def isDone(self, name):
        usrnum = self.getUserByName(name)
        return self.complete[usrnum]
            
    def allDone(self):
        for val in self.complete:
            if not val: return False
        return True
    
    def getUsers(self):
        return self.internalList
    
    def getNumberOfPlayers(self):
        return len(self.internalList)
    
    def clearUserList(self):
        self.internalList = []
        self.listOfUsers.clear()
